package config

import (
	"encoding/json"
	"os"
	"path/filepath"
	"sync"

	"github.com/pkg/errors"
)

// AppConfig 应用配置
type AppConfig struct {
	// 应用基础配置
	App AppSettings `json:"app"`

	// 数据库配置
	Database DatabaseSettings `json:"database"`

	// 日志配置
	Logging LoggingSettings `json:"logging"`

	// 安全配置
	Security SecuritySettings `json:"security"`

	// 性能配置
	Performance PerformanceSettings `json:"performance"`

	// UI配置
	UI UISettings `json:"ui"`

	// 插件配置
	Plugins PluginSettings `json:"plugins"`
}

// AppSettings 应用设置
type AppSettings struct {
	Name        string `json:"name"`
	Version     string `json:"version"`
	Environment string `json:"environment"` // development, production
	Debug       bool   `json:"debug"`
	Language    string `json:"language"`
	TimeZone    string `json:"timezone"`
}

// DatabaseSettings 数据库设置
type DatabaseSettings struct {
	MaxConnections     int    `json:"maxConnections"`
	ConnectionTimeout  int    `json:"connectionTimeout"` // 秒
	QueryTimeout       int    `json:"queryTimeout"`      // 秒
	MaxRetries         int    `json:"maxRetries"`
	RetryDelay         int    `json:"retryDelay"` // 毫秒
	EnableQueryLogging bool   `json:"enableQueryLogging"`
	QueryLogLevel      string `json:"queryLogLevel"`      // all, slow, error
	SlowQueryThreshold int    `json:"slowQueryThreshold"` // 毫秒
}

// LoggingSettings 日志设置
type LoggingSettings struct {
	Level      string `json:"level"`  // debug, info, warn, error
	Format     string `json:"format"` // json, text
	Output     string `json:"output"` // console, file, both
	FilePath   string `json:"filePath"`
	MaxSize    int    `json:"maxSize"` // MB
	MaxBackups int    `json:"maxBackups"`
	MaxAge     int    `json:"maxAge"` // 天
	Compress   bool   `json:"compress"`
}

// SecuritySettings 安全设置
type SecuritySettings struct {
	EnableSSL           bool     `json:"enableSSL"`
	TrustedHosts        []string `json:"trustedHosts"`
	EnableRateLimit     bool     `json:"enableRateLimit"`
	RateLimitRequests   int      `json:"rateLimitRequests"`
	RateLimitWindow     int      `json:"rateLimitWindow"` // 秒
	EncryptionAlgorithm string   `json:"encryptionAlgorithm"`
	SessionTimeout      int      `json:"sessionTimeout"` // 分钟
}

// PerformanceSettings 性能设置
type PerformanceSettings struct {
	EnableCache        bool `json:"enableCache"`
	CacheSize          int  `json:"cacheSize"` // MB
	CacheTTL           int  `json:"cacheTTL"`  // 秒
	EnableCompression  bool `json:"enableCompression"`
	CompressionLevel   int  `json:"compressionLevel"`
	MaxConcurrentTasks int  `json:"maxConcurrentTasks"`
}

// UISettings UI设置
type UISettings struct {
	Theme              string            `json:"theme"` // light, dark, auto
	FontSize           int               `json:"fontSize"`
	ShowLineNumbers    bool              `json:"showLineNumbers"`
	WordWrap           bool              `json:"wordWrap"`
	SyntaxHighlighting bool              `json:"syntaxHighlighting"`
	AutoComplete       bool              `json:"autoComplete"`
	TabSize            int               `json:"tabSize"`
	Layout             map[string]string `json:"layout"`
	Shortcuts          map[string]string `json:"shortcuts"`
}

// PluginSettings 插件设置
type PluginSettings struct {
	Enabled     bool              `json:"enabled"`
	Directory   string            `json:"directory"`
	AutoUpdate  bool              `json:"autoUpdate"`
	Marketplace string            `json:"marketplace"`
	Installed   []InstalledPlugin `json:"installed"`
}

// InstalledPlugin 已安装插件
type InstalledPlugin struct {
	ID      string `json:"id"`
	Name    string `json:"name"`
	Version string `json:"version"`
	Enabled bool   `json:"enabled"`
}

// ConfigManager 配置管理器
type ConfigManager struct {
	config     *AppConfig
	configPath string
	mu         sync.RWMutex
	onChange   []func(*AppConfig)
}

// NewConfigManager 创建配置管理器
func NewConfigManager(configPath string) (*ConfigManager, error) {
	cm := &ConfigManager{
		configPath: configPath,
		onChange:   make([]func(*AppConfig), 0),
	}

	// 加载配置
	if err := cm.Load(); err != nil {
		// 如果配置文件不存在，创建默认配置
		if os.IsNotExist(err) {
			cm.config = DefaultConfig()
			if err := cm.Save(); err != nil {
				return nil, errors.Wrap(err, "failed to save default config")
			}
		} else {
			return nil, err
		}
	}

	return cm, nil
}

// Load 加载配置
func (cm *ConfigManager) Load() error {
	cm.mu.Lock()
	defer cm.mu.Unlock()

	data, err := os.ReadFile(cm.configPath)
	if err != nil {
		return errors.Wrap(err, "failed to read config file")
	}

	var config AppConfig
	if err := json.Unmarshal(data, &config); err != nil {
		return errors.Wrap(err, "failed to unmarshal config")
	}

	cm.config = &config
	return nil
}

// Save 保存配置
func (cm *ConfigManager) Save() error {
	cm.mu.RLock()
	defer cm.mu.RUnlock()

	// 确保目录存在
	dir := filepath.Dir(cm.configPath)
	if err := os.MkdirAll(dir, 0755); err != nil {
		return errors.Wrap(err, "failed to create config directory")
	}

	data, err := json.MarshalIndent(cm.config, "", "  ")
	if err != nil {
		return errors.Wrap(err, "failed to marshal config")
	}

	if err := os.WriteFile(cm.configPath, data, 0644); err != nil {
		return errors.Wrap(err, "failed to write config file")
	}

	// 触发变更回调
	for _, fn := range cm.onChange {
		go fn(cm.config)
	}

	return nil
}

// Get 获取配置
func (cm *ConfigManager) Get() *AppConfig {
	cm.mu.RLock()
	defer cm.mu.RUnlock()

	// 返回配置的副本
	configCopy := *cm.config
	return &configCopy
}

// Update 更新配置
func (cm *ConfigManager) Update(updater func(*AppConfig)) error {
	cm.mu.Lock()
	defer cm.mu.Unlock()

	// 创建配置副本
	configCopy := *cm.config

	// 应用更新
	updater(&configCopy)

	// 验证配置
	if err := ValidateConfig(&configCopy); err != nil {
		return errors.Wrap(err, "invalid config")
	}

	// 更新配置
	cm.config = &configCopy

	// 保存到文件
	return cm.Save()
}

// OnChange 注册配置变更回调
func (cm *ConfigManager) OnChange(fn func(*AppConfig)) {
	cm.mu.Lock()
	defer cm.mu.Unlock()

	cm.onChange = append(cm.onChange, fn)
}

// DefaultConfig 默认配置
func DefaultConfig() *AppConfig {
	return &AppConfig{
		App: AppSettings{
			Name:        "Database Manager",
			Version:     "1.0.0",
			Environment: "development",
			Debug:       true,
			Language:    "en",
			TimeZone:    "UTC",
		},
		Database: DatabaseSettings{
			MaxConnections:     25,
			ConnectionTimeout:  30,
			QueryTimeout:       300,
			MaxRetries:         3,
			RetryDelay:         1000,
			EnableQueryLogging: true,
			QueryLogLevel:      "slow",
			SlowQueryThreshold: 1000,
		},
		Logging: LoggingSettings{
			Level:      "info",
			Format:     "json",
			Output:     "both",
			FilePath:   "logs/app.log",
			MaxSize:    100,
			MaxBackups: 3,
			MaxAge:     30,
			Compress:   true,
		},
		Security: SecuritySettings{
			EnableSSL:           false,
			TrustedHosts:        []string{"localhost", "127.0.0.1"},
			EnableRateLimit:     true,
			RateLimitRequests:   100,
			RateLimitWindow:     60,
			EncryptionAlgorithm: "AES-256",
			SessionTimeout:      30,
		},
		Performance: PerformanceSettings{
			EnableCache:        true,
			CacheSize:          100,
			CacheTTL:           300,
			EnableCompression:  true,
			CompressionLevel:   6,
			MaxConcurrentTasks: 10,
		},
		UI: UISettings{
			Theme:              "auto",
			FontSize:           14,
			ShowLineNumbers:    true,
			WordWrap:           false,
			SyntaxHighlighting: true,
			AutoComplete:       true,
			TabSize:            4,
			Layout:             make(map[string]string),
			Shortcuts:          make(map[string]string),
		},
		Plugins: PluginSettings{
			Enabled:     true,
			Directory:   "plugins",
			AutoUpdate:  true,
			Marketplace: "https://plugins.dbmanager.io",
			Installed:   []InstalledPlugin{},
		},
	}
}

// ValidateConfig 验证配置
func ValidateConfig(config *AppConfig) error {
	// 验证应用设置
	if config.App.Name == "" {
		return errors.New("app name is required")
	}

	// 验证数据库设置
	if config.Database.MaxConnections < 1 {
		return errors.New("max connections must be at least 1")
	}

	if config.Database.ConnectionTimeout < 1 {
		return errors.New("connection timeout must be at least 1 second")
	}

	// 验证日志设置
	validLevels := map[string]bool{"debug": true, "info": true, "warn": true, "error": true}
	if !validLevels[config.Logging.Level] {
		return errors.New("invalid log level")
	}

	// 验证性能设置
	if config.Performance.MaxConcurrentTasks < 1 {
		return errors.New("max concurrent tasks must be at least 1")
	}

	return nil
}
